﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.Timers;

namespace SpriteEditor
{
    public partial class frmMain : Form
    {
        //Variables
        //Common variables ------------------------------
		Bitmap bufferBitmap;
        public bool isCtrPressedOnMainForm = false;

        public const int MODULE_BITMAP_WIDTH = 100; // Variables for module show in the flow module panel
        public const int SAVE_TASK_NUM = 5; // Variables for module show in the flow module panel

        const int MAIN_TAB_MODULES_EDITOR = 0;
        const int MAIN_TAB_FRAMES_EDITOR = 1;
        const int MAIN_TAB_ANIMATIONS_EDITOR = 2;

        public Color CURRENT_SELECTION_COLOR = Color.FromArgb(0xFF, 0x00, 0xFF, 0xFF);
        public Color EMPTY_CONTROL_COLOR = Color.FromArgb(0xFF, 0xFF, 0x00, 0xFF);

        public static Sprite spr { get; set; }
        
        //Module editor variables -----------------------

        public Point root_Modules_Grid_Default_Pos { get; set; }
        public Point root_Modules_Grid_Pos { get; set; }
        public Point root_Modules_Grid_Pos_Scale { get; set; }        

        ModuleSelection CurSel_Module { get; set; }
     
        public Point mouseCurrentPos { get; set; }
        public bool ModulePanelMouseDown { get; set; }
        public Point ModulePanelMouseDownPos { get; set; }

        public int modules_editor_mode { get; set; }

        const int PANEL_MOVE_ROOT_MODE = 0;
        const int PANEL_EDIT_RECT_MODE = 1;

        public int modules_edit_state { get; set; }

        const int MODULE_RESIZE_NONE = 0;
        const int MODULE_RESIZE_MOVE = 1;
        const int MODULE_RESIZE_TOP = 2;
        const int MODULE_RESIZE_BOTTOM = 3;
        const int MODULE_RESIZE_LEFT = 4;
        const int MODULE_RESIZE_RIGHT = 5;
        public const int TOP_LEFT = 6;
        public const int BUTTOM_LEFT = 7;
        public const int BUTTOM_RIGHT = 8;
        public const int TOP_RIGHT = 9; 
        public bool panelModulesMouseDrag = false;
        public bool isKeyCtrPressed = false;
        bool isArrowKeyPressed = false;

        //public static int currentModuleIdUsed = 999;

        //Frame editor variables -----------------------

        public Point root_Frames_Grid_Default_Pos { get; set; }
        public Point root_Frames_Grid_Pos { get; set; }

        FrameSelection CurSel_Frame { get; set; }
        public bool FramePanelMouseDown { get; set; }
        public Point FramePanelMouseDownPos { get; set; }

        public int frames_editor_mode { get; set; }
        public int frames_edit_state { get; set; }

        const int FRAME_EDIT_NONE = 0;
        const int FRAME_EDIT_MOVE = 1;

        public bool panelFramesMouseDrag = false;

        public int curModuleIndexInFrameFlow = -1;

        //public static int currentFrameIdUsed = 1999;

        //Animation editor variables -----------------------

        public Point root_Animations_Grid_Default_Pos { get; set; }
        public Point root_Animations_Grid_Pos { get; set; }

        AnimationSelection CurSel_Animation { get; set; }
        public bool AnimationPanelMouseDown { get; set; }
        public Point AnimationPanelMouseDownPos { get; set; }

        public int animations_editor_mode { get; set; }
        public int animations_edit_state { get; set; }

        const int ANIMATION_EDIT_NONE = 0;
        const int ANIMATION_EDIT_MOVE = 1;

        public bool panelAnimationsMouseDrag = false;

        public bool is_PlayingAnim { get; set; }

        public int curFrameIndexInAnimFlow = -1;
        //public static int currentAnimIdUsed = 2999;
        public static  float m_ZoomInModule = 1f;

        //========================================================================
        // Common functions
        //========================================================================
        public void moveModule(int moduleIndex, int dx, int dy)
        {
            spr.lst_Modules[moduleIndex].X += dx;
            spr.lst_Modules[moduleIndex].Y += dy;
            refreshModuleGrid();
            DrawPanelModule();
            //saveModuleTask();
        }

        public void moveLeftModule(int moduleIndex)
        {
            moveModule(moduleIndex, -1, 0);
        }

        public void moveRightModule(int moduleIndex)
        {
            moveModule(moduleIndex, +1, 0);
        }

        public void moveUpModule(int moduleIndex)
        {
            moveModule(moduleIndex, 0, -1);
        }

        public void moveDownModule(int moduleIndex)
        {
            moveModule(moduleIndex, 0, +1);
        }

        public void exPandLeftModule(int moduleIndex)
        {
            spr.lst_Modules[moduleIndex].W -= 1;
            refreshModuleGrid();
            DrawPanelModule();
            //saveModuleTask();
        }

        public void exPandRightModule(int moduleIndex)
        {
            spr.lst_Modules[moduleIndex].W += 1;
            refreshModuleGrid();
            DrawPanelModule();
            //saveModuleTask();
        }

        public void exPandUpModule(int moduleIndex)
        {
            spr.lst_Modules[moduleIndex].H -= 1;
            refreshModuleGrid();
            DrawPanelModule();
            //saveModuleTask();
        }

        public void exPandDownModule(int moduleIndex)
        {
            spr.lst_Modules[moduleIndex].H += 1;
            refreshModuleGrid();
            DrawPanelModule();
            //saveModuleTask();
        }

        //========================================================================
        // Main Form functions
        //========================================================================

        public frmMain(String[] args)
        {
            InitializeComponent();

            if (args.Length > 0)
            {
                //MessageBox.Show(args[0]);
                spr = new Sprite();
                spr.sprite_FileName = args[0];

                ImportSprite(spr);
            }
            else
            {
                FillDefautData();
                //FillDefautDataForDebugging();
            }

            //Init Modules Variable
            dataGridView_Modules.AutoGenerateColumns = false;

            root_Modules_Grid_Default_Pos = new Point(panel_Modules.Width / 2, panel_Modules.Height / 2);
            root_Modules_Grid_Pos = new Point(panel_Modules.Width / 2, panel_Modules.Height / 2);
            root_Modules_Grid_Pos_Scale =  new Point(panel_Modules.Width / 2, panel_Modules.Height / 2);

            modules_editor_mode = PANEL_EDIT_RECT_MODE;
            modules_edit_state = MODULE_RESIZE_NONE;

            //Init Frames Variable
            dataGridView_Frames.AutoGenerateColumns = false;
            dataGridView_ModulesOfFrame.AutoGenerateColumns = false;

            root_Frames_Grid_Default_Pos = new Point(panel_Frames.Width / 2, panel_Frames.Height / 2);
            root_Frames_Grid_Pos = new Point(panel_Frames.Width / 2, panel_Frames.Height / 2);

            frames_editor_mode = PANEL_EDIT_RECT_MODE;
            frames_edit_state = FRAME_EDIT_NONE;

            //Init Animations Variable
            dataGridView_Animations.AutoGenerateColumns = false;
            dataGridView_FramesOfAnimation.AutoGenerateColumns = false;

            root_Animations_Grid_Default_Pos = new Point(panel_Animations.Width / 2, panel_Animations.Height / 2);
            root_Animations_Grid_Pos = new Point(panel_Animations.Width / 2, panel_Animations.Height / 2);

            is_PlayingAnim = false;
            numericUpDown_FPS.Value = 20;
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            ResizeForm();
            //saveModuleTask();
        }

        private void frmMain_SizeChanged(object sender, EventArgs e)
        {
            ResizeForm();
            if (tabControl_Main.SelectedIndex == MAIN_TAB_MODULES_EDITOR)
            {
                DrawPanelModule();
            }
            else if (tabControl_Main.SelectedIndex == MAIN_TAB_FRAMES_EDITOR)
            {
                DrawPanelFrame();
                DrawFlowPanelFrame();
            }
            else if (tabControl_Main.SelectedIndex == MAIN_TAB_ANIMATIONS_EDITOR)
            {
                DrawPanelAnimation();
                DrawFlowPanelAnimation();
            }
        }

        private void tabControl_Main_SelectedIndexChanged(object sender, EventArgs e)
        {
            ResizeForm();
            if (tabControl_Main.SelectedIndex == MAIN_TAB_MODULES_EDITOR)
            {
                DrawPanelModule();
            }
            else if (tabControl_Main.SelectedIndex == MAIN_TAB_FRAMES_EDITOR)
            {
                if(spr.lst_Modules != null && spr.lst_Modules.Count > 0)
                curModuleIndexInFrameFlow = 0;
                UpdateListModuleImages();

                DrawPanelFrame();
                DrawFlowPanelFrame();
            }
            else if (tabControl_Main.SelectedIndex == MAIN_TAB_ANIMATIONS_EDITOR)
            {
                curFrameIndexInAnimFlow = 0;
                UpdateListModuleImages();
                UpdateListFrameImages();

                DrawPanelAnimation();
                DrawFlowPanelAnimation();
            }
            StopAnim();
        }

        private void tabControl_Main_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ControlKey)
            {
                isKeyCtrPressed = true;
            }

            isArrowKeyPressed = e.KeyCode == Keys.Up || e.KeyCode == Keys.Down ||
                     e.KeyCode == Keys.Left || e.KeyCode == Keys.Right;

            e.Handled = isArrowKeyPressed;

            switch (tabControl_Main.SelectedIndex)
            {
                case MAIN_TAB_MODULES_EDITOR:
                    if (CurSel_Module != null && !b_isModuleCellEditting)
                    {
                        if (isKeyCtrPressed)
                        {
                            switch (e.KeyCode)
                            {
                                case Keys.Left:
                                    exPandLeftModule(CurSel_Module.CurrentModuleIndex);
                                    break;

                                case Keys.Right:
                                    exPandRightModule(CurSel_Module.CurrentModuleIndex);
                                    break;

                                case Keys.Up:
                                    exPandUpModule(CurSel_Module.CurrentModuleIndex);
                                    break;

                                case Keys.Down:
                                    exPandDownModule(CurSel_Module.CurrentModuleIndex);
                                    break;

                                case Keys.Z:
                                    //undoModuleTask();
                                    break;

                                case Keys.Y:
                                    //redoModuleTask();
                                    break;

                                case Keys.N:
                                    newModule();
                                    break;

                                case Keys.D:
                                    cloneModule();
                                    break;

                            }
                        }
                        else
                        {
                            switch (e.KeyCode)
                            {
                                case Keys.Left:
                                    moveLeftModule(CurSel_Module.CurrentModuleIndex);
                                    break;

                                case Keys.Right:

                                    moveRightModule(CurSel_Module.CurrentModuleIndex);
                                    break;
                                case Keys.Up:

                                    moveUpModule(CurSel_Module.CurrentModuleIndex);
                                    break;
                                case Keys.Down:

                                    moveDownModule(CurSel_Module.CurrentModuleIndex);
                                    break;
                            }
                        }
                    }
                    break;
                case MAIN_TAB_FRAMES_EDITOR:
                    break;
                case MAIN_TAB_ANIMATIONS_EDITOR:
                    break;
            }
        }

        private void tabControl_Main_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ControlKey)
            {
                isKeyCtrPressed = false;
            }
            isArrowKeyPressed = e.KeyCode == Keys.Up || e.KeyCode == Keys.Down ||
                      e.KeyCode == Keys.Left || e.KeyCode == Keys.Right;
            e.Handled = isArrowKeyPressed;
        }

        private void tabControl_Main_KeyPress(object sender, KeyPressEventArgs e)
        {

        }

        //Menu strip functions
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RemoveAll();
            ReFreshAll();
            FillDefautData();
            this.Refresh();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadSprite();
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveSprite();
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RemoveAll();
            ReFreshAll();
            FillDefautData();
            this.Refresh();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void toolStripButton_LoadSprite_Click(object sender, EventArgs e)
        {
            LoadSprite();
        }

        private void frmMain_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ControlKey)
                isCtrPressedOnMainForm = true;
        }

        private void frmMain_KeyUp(object sender, KeyEventArgs e)
        {
            if (isCtrPressedOnMainForm)
            {
                switch (e.KeyCode)
                {
                    case Keys.S:
                        SaveSprite();
                        break;
                    case Keys.O:
                        LoadSprite();
                        break;
                }
            }
            if (e.KeyCode == Keys.ControlKey)
                isCtrPressedOnMainForm = false;
        }

        private void frmMain_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Copy; // Okay
            else
                e.Effect = DragDropEffects.None; // Unknown data, ignore it
        }

        private void frmMain_DragDrop(object sender, DragEventArgs e)
        {
            // Extract the data from the DataObject-Container into a string list
            String[] FileList = (String[])e.Data.GetData(DataFormats.FileDrop, false);

            // Do something with the data...

            // For example add all files into a simple label control:
            if (FileList.Length == 1)
            {
                LoadSprite(FileList[0]);
            }

            //foreach (String File in FileList)
            //    this.Text += File + "\n";

        }

        //========================================================================
        // Module tab functions
        //========================================================================

        private void button_LoadImage_Click(object sender, EventArgs e)
        {
            LoadImage();
        }

        private void button_saveImage_Click(object sender, EventArgs e)
        {
            SaveImage();
        }

        private void button_TranspImage_Click(object sender, EventArgs e)
        {
            transparentImage();
        }

        private void button_NewModule_Click(object sender, EventArgs e)
        {
            newModule();
        }

        private void button_DeleteModule_Click(object sender, EventArgs e)
        {
            deleteModule();
        }

        private void button_CloneModule_Click(object sender, EventArgs e)
        {
            cloneModule();
        }

        private void button_UpModule_Click(object sender, EventArgs e)
        {
            upModule();
        }

        private void button_DownModule_Click(object sender, EventArgs e)
        {
            downModule();
        }

        bool bModuleUpdateSelection = true;
        private void dataGridView_Modules_SelectionChanged(object sender, EventArgs e)
        {
            if (bModuleUpdateSelection == true)
            {
                updateCurModuleSelection();
                DrawPanelModule();
            }
            bModuleUpdateSelection = true;
        }

        bool b_isModuleCellEditting = false;
        private void dataGridView_Modules_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            b_isModuleCellEditting = true;
        }

        private void dataGridView_Modules_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            b_isModuleCellEditting = false;
            updateCurModuleSelection();
            DrawPanelModule();
        }

        private void dataGridView_Modules_MouseUp(object sender, MouseEventArgs e)
        {
            if (spr == null || spr.lst_Modules == null || spr.lst_Modules.Count == 0
                || dataGridView_Modules.Rows == null
                || dataGridView_Modules.Rows.Count == 0)
                return;

            if (e.Button == MouseButtons.Right)
            {
                DataGridView.HitTestInfo hit = dataGridView_Modules.HitTest(e.X, e.Y);

                // Only RowHeader and Cells (which make up a row) should fire a menu
                if (hit.Type == DataGridViewHitTestType.RowHeader
                    || hit.Type == DataGridViewHitTestType.Cell
                    && hit.RowIndex >= 0)
                {
                    // Notice how I assign the menu to the dataGridView below...

                    dataGridView_Modules.CurrentCell = dataGridView_Modules.Rows[hit.RowIndex].Cells[0];
                    dataGridView_Modules.ClearSelection();
                    dataGridView_Modules.Rows[hit.RowIndex].Selected = true;
                    dataGridView_Modules.ContextMenuStrip = contextMenuStripGridModules;
                    dataGridView_Modules.ContextMenuStrip.Show(this.dataGridView_Modules, new Point(e.X, e.Y));
                }

                // and then I remove the menu here...
                // This is because after we assign it to the dataGridView
                // it allows you to right-click anywhere on the control to
                // get a menu.  Try removing this line and expirement.
                dataGridView_Modules.ContextMenuStrip = null;
            }
        }

        private void iMAGEToolStripMenuItem_Click(object sender, EventArgs e)
        {
            changeModuleType(XmlEngine.TYPE_IMAGE);
        }

        private void rECTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            changeModuleType(XmlEngine.TYPE_RECT);
        }

        private void fILLRECTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            changeModuleType(XmlEngine.TYPE_FILL_RECT);
        }

        private void panel_Modules_Paint(object sender, PaintEventArgs e)
        {
            DrawPanelModule();
        }

        private void checkBox_DrawImages_CheckedChanged(object sender, EventArgs e)
        {
            //CurSel_Module = null;
            DrawPanelModule();
        }

        private void checkBox_DrawNoneImages_CheckedChanged(object sender, EventArgs e)
        {
            //CurSel_Module = null;
            DrawPanelModule();
        }

        private void panel_Modules_MouseDown(object sender, MouseEventArgs e)
        {
            panelModulesMouseDrag = true;
            //if (spr == null || spr.spr_image == null || spr.sprite_FileName == null)
            if (spr == null || spr.spr_image == null)
                return;

            if (e.Button == MouseButtons.Right)
            {

            }
            else if (e.Button == MouseButtons.Left)
            {
                if (modules_editor_mode == PANEL_MOVE_ROOT_MODE)
                {

                }
                else if (modules_editor_mode == PANEL_EDIT_RECT_MODE)
                {
                    if (spr.lst_Modules != null && CurSel_Module != null)
                    {
                    	  int scaleRectX = (int)(spr.lst_Modules[CurSel_Module.CurrentModuleIndex].X * m_ZoomInModule);
	        int scaleRectY = (int)(spr.lst_Modules[CurSel_Module.CurrentModuleIndex].Y * m_ZoomInModule);
	        int scaleRectW = (int)(spr.lst_Modules[CurSel_Module.CurrentModuleIndex].W * m_ZoomInModule);
	        int scaleRectH = (int)(spr.lst_Modules[CurSel_Module.CurrentModuleIndex].H * m_ZoomInModule);
            Rectangle currentRectModuleScale = new Rectangle(scaleRectX,scaleRectY,scaleRectW,scaleRectH);
                        Rectangle currentRect = SpriteCalculation.ConvertToRoot(currentRectModuleScale, root_Modules_Grid_Pos_Scale);
						int coner = SpriteCalculation.wichCornerPointInRect(e.Location, currentRect);
                        if (coner != -1)
                        {
                            modules_edit_state = coner;
                        }
						else
                        if (SpriteCalculation.IsPointAtMiddleOfRect(e.Location, currentRect))
                        {
                            modules_edit_state = MODULE_RESIZE_MOVE;
                        }
                        else if (SpriteCalculation.IsPointAtTopLineOfRect(e.Location, currentRect))
                        {
                            modules_edit_state = MODULE_RESIZE_TOP;
                        }
                        else if (SpriteCalculation.IsPointAtBottomLineOfRect(e.Location, currentRect))
                        {
                            modules_edit_state = MODULE_RESIZE_BOTTOM;
                        }
                        else if (SpriteCalculation.IsPointAtLeftLineOfRect(e.Location, currentRect))
                        {
                            modules_edit_state = MODULE_RESIZE_LEFT;
                        }
                        else if (SpriteCalculation.IsPointAtRightLineOfRect(e.Location, currentRect))
                        {
                            modules_edit_state = MODULE_RESIZE_RIGHT;
                        }
                        else
                        {
                            modules_edit_state = MODULE_RESIZE_NONE;
                        }
                    }
                }
            }
            ModulePanelMouseDown = true;
            ModulePanelMouseDownPos = e.Location;
            //CurSel_Module.P1 = CurSel_Module.P2 = e.Location;
        }
        private void panel_Modules_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta > 60)
                m_ZoomInModule += 0.1f;
            else if (e.Delta < -60)
                m_ZoomInModule -= 0.1f;   
            if(m_ZoomInModule <0.1f)
            	m_ZoomInModule = 0.1f;
               if(m_ZoomInModule > 10f)
            	m_ZoomInModule = 10f ;       		
            root_Modules_Grid_Pos_Scale  =  new Point((int)(root_Modules_Grid_Pos.X*m_ZoomInModule), (int)( root_Modules_Grid_Pos.Y*m_ZoomInModule));
            DrawPanelModule();
        }

        private void panel_Modules_MouseUp(object sender, MouseEventArgs e)
        {
            refreshModuleGrid();
            panelModulesMouseDrag = false;
            //if (spr == null || spr.spr_image == null || spr.spr_image_FileName == null)
            if (spr == null || spr.spr_image == null)
                return;

            if (e.Button == MouseButtons.Right)
            {
                modules_editor_mode++;
                modules_editor_mode = modules_editor_mode % 2;
                DrawPanelModule();
            }
            else if (e.Button == MouseButtons.Left)
            {
                if (modules_editor_mode == PANEL_MOVE_ROOT_MODE)
                {

                }
                else if (modules_editor_mode == PANEL_EDIT_RECT_MODE)
                {
                    if (modules_edit_state == MODULE_RESIZE_NONE)
                    {
                        if (spr.lst_Modules != null)
                        {
                        	Point cursorLocation = SpriteCalculation.DeConvertToRoot(e.Location, root_Modules_Grid_Pos_Scale);
                        	int dx = (int)(cursorLocation.X/m_ZoomInModule );
        					int dy = (int)(cursorLocation.Y/m_ZoomInModule);   
        					cursorLocation = new Point(dx,dy);
                            int cur_ModuleIndex = spr.getModuleIndexFromPosition(cursorLocation);
                            if (cur_ModuleIndex >= 0)
                            {
                                if ((spr.lst_Modules[cur_ModuleIndex].isImageType() && checkBox_DrawImages.Checked)
                                    || (spr.lst_Modules[cur_ModuleIndex].isNoneImageType() && checkBox_DrawNoneImages.Checked))
                                {
                                    if (CurSel_Module == null)
                                        CurSel_Module = new ModuleSelection();
                                    CurSel_Module.CurrentModuleIndex = cur_ModuleIndex;
                                    CurSel_Module.P1 = new Point(spr.lst_Modules[cur_ModuleIndex].X, spr.lst_Modules[cur_ModuleIndex].Y);
                                    CurSel_Module.P2 = new Point(spr.lst_Modules[cur_ModuleIndex].X + spr.lst_Modules[cur_ModuleIndex].W,
                                                                 spr.lst_Modules[cur_ModuleIndex].Y + spr.lst_Modules[cur_ModuleIndex].H);
                                }
                                else
                                {
                                    CurSel_Module = null;
                                }
                            }
                            else
                            {
                                CurSel_Module = null;
                            }
                            DrawPanelModule();
                            updateModulesGridFromCurSel_Module();
                        }
                    }
                }
            }
            ModulePanelMouseDown = false;
            modules_edit_state = MODULE_RESIZE_NONE;

            //if (haveModifiedModule())
            //    saveModuleTask();
        }

        private void panel_Modules_MouseMove(object sender, MouseEventArgs e)
        {        	       
           mouseCurrentPos = e.Location;

            //if (spr == null || spr.spr_image == null || spr.spr_image_FileName == null)
            if (spr == null || spr.spr_image == null)
                return;

            //Modify consor
            if (modules_editor_mode == PANEL_MOVE_ROOT_MODE)
            {
                panel_Modules.Cursor = System.Windows.Forms.Cursors.Hand;
                if (ModulePanelMouseDown)
                {
                	int dx = (int)((e.Location.X - ModulePanelMouseDownPos.X)/m_ZoomInModule);
                	int dy = (int)((e.Location.Y - ModulePanelMouseDownPos.Y)/m_ZoomInModule);
                    int offsetMoveX = e.Location.X - ModulePanelMouseDownPos.X - (int)(dx*m_ZoomInModule);
                    int offsetMoveY = e.Location.Y - ModulePanelMouseDownPos.Y - (int)(dy*m_ZoomInModule);	
                    root_Modules_Grid_Pos = new Point(dx + root_Modules_Grid_Pos.X, dy + root_Modules_Grid_Pos.Y);
                    root_Modules_Grid_Pos_Scale = new Point((int)(root_Modules_Grid_Pos.X*m_ZoomInModule),(int)(root_Modules_Grid_Pos.Y*m_ZoomInModule));
                   
                    ModulePanelMouseDownPos = new Point(  e.Location.X - offsetMoveX,  e.Location.Y - offsetMoveY );
                    DrawPanelModule();
                }
            }
            else if (modules_editor_mode == PANEL_EDIT_RECT_MODE)
            {
                if (spr.lst_Modules != null && CurSel_Module != null && spr.lst_Modules.Count >0)
                {
                	int scaleRectX = (int)(spr.lst_Modules[CurSel_Module.CurrentModuleIndex].X * m_ZoomInModule);
                    int scaleRectY = (int)(spr.lst_Modules[CurSel_Module.CurrentModuleIndex].Y * m_ZoomInModule);
                    int scaleRectW = (int)(spr.lst_Modules[CurSel_Module.CurrentModuleIndex].W * m_ZoomInModule);
                    int scaleRectH = (int)(spr.lst_Modules[CurSel_Module.CurrentModuleIndex].H * m_ZoomInModule);
                    int eLocationXScale = (int)(e.Location.X/m_ZoomInModule);
                      int eLocationYScale = (int)(e.Location.Y/m_ZoomInModule);
                      int ModulePanelMouseDownPosXscale = (int)(ModulePanelMouseDownPos.X/m_ZoomInModule);
                     int ModulePanelMouseDownPosYscale = (int)(ModulePanelMouseDownPos.Y/m_ZoomInModule);   
                    Rectangle currentRectModuleScale = new Rectangle(scaleRectX,scaleRectY,scaleRectW,scaleRectH);
                    switch (modules_edit_state)
                    {
                        case MODULE_RESIZE_NONE:
                    		
                            Rectangle currentRect = SpriteCalculation.ConvertToRoot(currentRectModuleScale, root_Modules_Grid_Pos_Scale);
							int corner = SpriteCalculation.wichCornerPointInRect(e.Location, currentRect);
                            if (corner != -1)
                            {
                                if (corner == BUTTOM_RIGHT || corner == TOP_LEFT)
                                {
                                    panel_Modules.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
                                }
                                else if (corner == TOP_RIGHT || corner == BUTTOM_LEFT)
                                {
                                    panel_Modules.Cursor = System.Windows.Forms.Cursors.SizeNESW;
                                }
                                
                            }
							else
                            if (SpriteCalculation.IsPointAtTopLineOfRect(e.Location, currentRect)
                                || SpriteCalculation.IsPointAtBottomLineOfRect(e.Location, currentRect))
                            {
                                panel_Modules.Cursor = System.Windows.Forms.Cursors.SizeNS;
                            }
                            else if (SpriteCalculation.IsPointAtLeftLineOfRect(e.Location, currentRect)
                                || SpriteCalculation.IsPointAtRightLineOfRect(e.Location, currentRect))
                            {
                                panel_Modules.Cursor = System.Windows.Forms.Cursors.SizeWE;
                            }
                            else if (SpriteCalculation.IsPointAtMiddleOfRect(e.Location, currentRect))
                            {
                                panel_Modules.Cursor = System.Windows.Forms.Cursors.SizeAll;
                            }
                            else
                            {
                                panel_Modules.Cursor = System.Windows.Forms.Cursors.Default;
                            }
                            break;
                        case MODULE_RESIZE_MOVE:
                            if (ModulePanelMouseDown && ModulePanelMouseDownPos != null)
                            {
                            	CurSel_Module.P1 = new Point(CurSel_Module.P1.X + (eLocationXScale -ModulePanelMouseDownPosXscale),
                                                        CurSel_Module.P1.Y + (eLocationYScale - ModulePanelMouseDownPosYscale));
                                CurSel_Module.P2 = new Point(CurSel_Module.P2.X + (eLocationXScale - ModulePanelMouseDownPosXscale),
                                                        CurSel_Module.P2.Y + (eLocationYScale - ModulePanelMouseDownPosYscale));
                                spr.lst_Modules[CurSel_Module.CurrentModuleIndex].X = CurSel_Module.P1.X;
                                spr.lst_Modules[CurSel_Module.CurrentModuleIndex].Y = CurSel_Module.P1.Y;
                                ModulePanelMouseDownPos = e.Location;
                                DrawPanelModule();
                            }
                            break;
                        case MODULE_RESIZE_TOP:
                            if (panelModulesMouseDrag)
                            {
                                CurSel_Module.P1 = new Point(CurSel_Module.P1.X, CurSel_Module.P1.Y + (eLocationYScale - ModulePanelMouseDownPosYscale));
                                if (CurSel_Module.P2.Y - CurSel_Module.P1.Y > 0)
                                {
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].Y = CurSel_Module.P1.Y;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].H = CurSel_Module.P2.Y - CurSel_Module.P1.Y;

                                    ModulePanelMouseDownPos = e.Location;
                                }
                                DrawPanelModule();
                            }
                            break;
                        case MODULE_RESIZE_BOTTOM:
                            if (panelModulesMouseDrag)
                            {
                                CurSel_Module.P2 = new Point(CurSel_Module.P2.X, CurSel_Module.P2.Y + (eLocationYScale - ModulePanelMouseDownPosYscale));
                                if (CurSel_Module.P2.Y - CurSel_Module.P1.Y > 0)
                                {
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].Y = CurSel_Module.P1.Y;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].H = CurSel_Module.P2.Y - CurSel_Module.P1.Y;

                                    ModulePanelMouseDownPos = e.Location;
                                }
                                DrawPanelModule();
                            }
                            break;
                        case MODULE_RESIZE_LEFT:
                            if (panelModulesMouseDrag)
                            {
                                CurSel_Module.P1 = new Point(CurSel_Module.P1.X + (eLocationXScale - ModulePanelMouseDownPosXscale), CurSel_Module.P1.Y);
                                if (CurSel_Module.P2.X - CurSel_Module.P1.X > 0)
                                {
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].X = CurSel_Module.P1.X;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].W = CurSel_Module.P2.X - CurSel_Module.P1.X;

                                    ModulePanelMouseDownPos = e.Location;
                                }
                                DrawPanelModule();
                            }
                            break;
                        case MODULE_RESIZE_RIGHT:
                            if (panelModulesMouseDrag)
                            {
                                CurSel_Module.P2 = new Point(CurSel_Module.P2.X + (eLocationXScale - ModulePanelMouseDownPosXscale), CurSel_Module.P2.Y);
                                if (CurSel_Module.P2.X - CurSel_Module.P1.X > 0)
                                {
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].X = CurSel_Module.P1.X;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].W = CurSel_Module.P2.X - CurSel_Module.P1.X;

                                    ModulePanelMouseDownPos = e.Location;
                                }
                                DrawPanelModule();
                            }
                            break;
                        case TOP_LEFT:
                            if (panelModulesMouseDrag)
                            {
                                CurSel_Module.P1 = new Point(CurSel_Module.P1.X + (eLocationXScale - ModulePanelMouseDownPosXscale), CurSel_Module.P1.Y + (eLocationYScale - ModulePanelMouseDownPosYscale));
                                if (CurSel_Module.P2.Y - CurSel_Module.P1.Y > 0 && CurSel_Module.P2.X - CurSel_Module.P1.X >0)
                                {
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].Y = CurSel_Module.P1.Y;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].X = CurSel_Module.P1.X;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].W = CurSel_Module.P2.X - CurSel_Module.P1.X;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].H = CurSel_Module.P2.Y - CurSel_Module.P1.Y;

                                    ModulePanelMouseDownPos = e.Location;
                                }
                                DrawPanelModule();
                            }
                            break;
                        case BUTTOM_LEFT:
                            if (panelModulesMouseDrag)
                            {
                                CurSel_Module.P1 = new Point(CurSel_Module.P1.X + (eLocationXScale - ModulePanelMouseDownPosXscale), CurSel_Module.P1.Y);
                                CurSel_Module.P2 = new Point(CurSel_Module.P2.X, CurSel_Module.P2.Y + (eLocationYScale - ModulePanelMouseDownPosYscale));
                                if (CurSel_Module.P2.X - CurSel_Module.P1.X > 0 && CurSel_Module.P2.Y - CurSel_Module.P1.Y > 0)
                                {
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].X = CurSel_Module.P1.X;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].W = CurSel_Module.P2.X - CurSel_Module.P1.X;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].Y = CurSel_Module.P1.Y;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].H = CurSel_Module.P2.Y - CurSel_Module.P1.Y;

                                    ModulePanelMouseDownPos = e.Location;
                                }
                                DrawPanelModule();
                            }
                           
                            break;

                        case BUTTOM_RIGHT:
                            if (panelModulesMouseDrag)
                                if (panelModulesMouseDrag)
                                {
                                    CurSel_Module.P2 = new Point(CurSel_Module.P2.X + (eLocationXScale - ModulePanelMouseDownPosXscale), CurSel_Module.P2.Y + (eLocationYScale - ModulePanelMouseDownPosYscale));
                                    if (CurSel_Module.P2.Y - CurSel_Module.P1.Y > 0 && CurSel_Module.P2.X - CurSel_Module.P1.X > 0)
                                    {
                                        spr.lst_Modules[CurSel_Module.CurrentModuleIndex].Y = CurSel_Module.P1.Y;
                                        spr.lst_Modules[CurSel_Module.CurrentModuleIndex].X = CurSel_Module.P1.X;
                                        spr.lst_Modules[CurSel_Module.CurrentModuleIndex].W = CurSel_Module.P2.X - CurSel_Module.P1.X;
                                        spr.lst_Modules[CurSel_Module.CurrentModuleIndex].H = CurSel_Module.P2.Y - CurSel_Module.P1.Y;

                                        ModulePanelMouseDownPos = e.Location;
                                    }
                                    DrawPanelModule();
                                }
                            break;
                        case TOP_RIGHT:
                            if (panelModulesMouseDrag)
                            {
                                CurSel_Module.P1 = new Point(CurSel_Module.P1.X, CurSel_Module.P1.Y + (eLocationYScale - ModulePanelMouseDownPosYscale));
                                CurSel_Module.P2 = new Point(CurSel_Module.P2.X + (eLocationXScale - ModulePanelMouseDownPosXscale), CurSel_Module.P2.Y);
                                if (CurSel_Module.P2.X - CurSel_Module.P1.X > 0 && CurSel_Module.P2.Y - CurSel_Module.P1.Y > 0)
                                {
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].X = CurSel_Module.P1.X;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].W = CurSel_Module.P2.X - CurSel_Module.P1.X;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].Y = CurSel_Module.P1.Y;
                                    spr.lst_Modules[CurSel_Module.CurrentModuleIndex].H = CurSel_Module.P2.Y - CurSel_Module.P1.Y;

                                    ModulePanelMouseDownPos = e.Location;
                                }
                                DrawPanelModule();
                            }
                            break;
                            
                    }
                }
                else
                {
                    panel_Modules.Cursor = System.Windows.Forms.Cursors.Default;
                }
            }

            //if (PanelMouseDown)
            //{
            //    CurSel_Module.P2 = e.Location;
            //    DrawPanelModule();
            //}
            drawStatusBar();
        }

        //========================================================================
        // Frame tab functions
        //========================================================================
        //Frame grid
        private void button_NewFrame_Click(object sender, EventArgs e)
        {
            addNewFrame();
        }

        private void button_DeleteFrame_Click(object sender, EventArgs e)
        {
            deleteFrame();
        }

        private void button_CloneFrame_Click(object sender, EventArgs e)
        {
            cloneFrame();
        }

        private void button_UpFrame_Click(object sender, EventArgs e)
        {
            upFrame();
        }

        private void button_DownFrame_Click(object sender, EventArgs e)
        {
            downFrame();
        }

        private void dataGridView_Frames_SelectionChanged(object sender, EventArgs e)
        {
            updateCurFrameSelection();
            DrawPanelFrame();
        }

        private void dataGridView_Frames_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            DrawPanelFrame();
        }

        //Module Of Frames Grid
        private void button_NewModuleOfFrame_Click(object sender, EventArgs e)
        {
            newModuleOfFrame();
        }

        private void button_DeleteModuleOfFrame_Click(object sender, EventArgs e)
        {
            deleteModuleOfFrame();
        }

        private void button_CloneModuleOfFrame_Click(object sender, EventArgs e)
        {
            cloneModuleOfFrame();
        }

        private void button_UpModuleOfFrame_Click(object sender, EventArgs e)
        {
            upModuleOfFrame();
        }

        private void button_DownModuleOfFrame_Click(object sender, EventArgs e)
        {
            downModuleOfFrame();
        }

        bool bFrameUpdateSelection = true;
        private void dataGridView_ModulesOfFrame_SelectionChanged(object sender, EventArgs e)
        {
            if (bFrameUpdateSelection == true)
            {
                updateCurMOFramesSelection();
            }
            bFrameUpdateSelection = true;
        }

        private void dataGridView_ModulesOfFrame_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            DrawPanelFrame();
        }

        private void dataGridView_ModulesOfFrame_MouseUp(object sender, MouseEventArgs e)
        {
            if (spr == null || spr.lst_Frames == null || spr.lst_Frames.Count == 0
                || dataGridView_Frames.CurrentRow == null
                || spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame == null
                || spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame.Count == 0
                || dataGridView_ModulesOfFrame.Rows == null
                || dataGridView_ModulesOfFrame.Rows.Count == 0)
                return;

            if (e.Button == MouseButtons.Right)
            {
                DataGridView.HitTestInfo hit = dataGridView_Modules.HitTest(e.X, e.Y);

                // Only RowHeader and Cells (which make up a row) should fire a menu
                if (hit.Type == DataGridViewHitTestType.RowHeader
                    || hit.Type == DataGridViewHitTestType.Cell
                    && hit.RowIndex >= 0)
                {
                    // Notice how I assign the menu to the dataGridView below...

                    dataGridView_ModulesOfFrame.CurrentCell = dataGridView_ModulesOfFrame.Rows[hit.RowIndex].Cells[0];
                    dataGridView_ModulesOfFrame.ClearSelection();
                    dataGridView_ModulesOfFrame.Rows[hit.RowIndex].Selected = true;
                    dataGridView_ModulesOfFrame.ContextMenuStrip = contextMenuStripGridModuleOfFrame;
                    dataGridView_ModulesOfFrame.ContextMenuStrip.Show(this.dataGridView_ModulesOfFrame, new Point(e.X, e.Y));
                }

                // and then I remove the menu here...
                // This is because after we assign it to the dataGridView
                // it allows you to right-click anywhere on the control to
                // get a menu.  Try removing this line and expirement.
                dataGridView_ModulesOfFrame.ContextMenuStrip = null;
            }
        }

        private void flipHorizontallyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int cur_FrameIndex = dataGridView_Frames.CurrentRow.Index;
            int cur_MOFndex = dataGridView_ModulesOfFrame.CurrentRow.Index;

            if (spr != null && spr.lst_Frames != null
                && spr.lst_Frames.Count > dataGridView_Frames.CurrentRow.Index
                && spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame != null
                && spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame.Count > cur_MOFndex)
            {
                spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame[cur_MOFndex].xorFlags(XmlEngine.FLAG_FLIP_X);
                dataGridView_ModulesOfFrame.Refresh();
                updateCurMOFramesSelection();
                DrawPanelFrame();
            }
        }

        private void flipVerticallyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int cur_FrameIndex = dataGridView_Frames.CurrentRow.Index;
            int cur_MOFndex = dataGridView_ModulesOfFrame.CurrentRow.Index;

            if (spr != null && spr.lst_Frames != null
                && spr.lst_Frames.Count > dataGridView_Frames.CurrentRow.Index
                && spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame != null
                && spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame.Count > cur_MOFndex)
            {
                spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame[cur_MOFndex].xorFlags(XmlEngine.FLAG_FLIP_Y);
                dataGridView_ModulesOfFrame.Refresh();
                updateCurMOFramesSelection();
                DrawPanelFrame();
            }
        }

        //Modules Flow Panel
        private void flowLayoutPanel_Frame_Paint(object sender, PaintEventArgs e)
        {
            //DrawFlowPanelFrame();
        }

        private void modules_flow_panel_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            OwnPanel modules_flow_panel = (OwnPanel)sender;

            //MessageBox.Show("Current index : " + modules_flow_panel.CurrentIndex.ToString());
            updateFlowPanelFrameSelection(modules_flow_panel.CurrentIndex);
            newModuleOfFrame();
        }

        private void modules_flow_panel_MouseClick(object sender, MouseEventArgs e)
        {
            OwnPanel modules_flow_panel = (OwnPanel)sender;
            updateFlowPanelFrameSelection(modules_flow_panel.CurrentIndex);
        }

        //Frame Panel
        private void panel_Frames_Paint(object sender, PaintEventArgs e)
        {
            DrawPanelFrame();
        }

        private void panel_Frames_MouseDown(object sender, MouseEventArgs e)
        {
            panelFramesMouseDrag = true;
            if (spr == null || spr.spr_image == null)// || spr.sprite_FileName == null)
                return;

            if (e.Button == MouseButtons.Right)
            {

            }
            else if (e.Button == MouseButtons.Left)
            {
                if (frames_editor_mode == PANEL_MOVE_ROOT_MODE)
                {

                }
                else if (frames_editor_mode == PANEL_EDIT_RECT_MODE)
                {
                    if (spr.lst_Frames != null 
                        && spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame != null 
                        && CurSel_Frame != null)
                    {
                        Rectangle currentRect = SpriteCalculation.ConvertToRoot(new Rectangle(CurSel_Frame.P1.X, CurSel_Frame.P1.Y,
                                                                            CurSel_Frame.P2.X - CurSel_Frame.P1.X,
                                                                            CurSel_Frame.P2.Y - CurSel_Frame.P1.Y),
                                                                            root_Frames_Grid_Pos);

                        if (SpriteCalculation.IsPointInRect(e.Location, currentRect))
                        {
                            frames_edit_state = FRAME_EDIT_MOVE;
                        }
                        else
                        {
                            frames_edit_state = FRAME_EDIT_NONE;
                        }
                    }
                }
            }
            FramePanelMouseDown = true;
            FramePanelMouseDownPos = e.Location;
        }

        private void panel_Frames_MouseUp(object sender, MouseEventArgs e)
        {
            panelFramesMouseDrag = false;
            //if (spr == null || spr.spr_image == null || spr.spr_image_FileName == null)
            if (spr == null || spr.spr_image == null)
                return;

            if (e.Button == MouseButtons.Right)
            {
                frames_editor_mode++;
                frames_editor_mode = frames_editor_mode % 2;
                DrawPanelFrame();
            }
            else if (e.Button == MouseButtons.Left)
            {
                if (frames_editor_mode == PANEL_MOVE_ROOT_MODE)
                {

                }
                else if (frames_editor_mode == PANEL_EDIT_RECT_MODE)
                {
                    if (spr.lst_Frames != null && dataGridView_Frames.CurrentRow != null
                        && spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame != null)
                    {
                        int cur_FrameIndex = dataGridView_Frames.CurrentRow.Index;

                        int cur_ModuleOfFrameIndex = spr.getModuleOfFrameIndexFromPosition(SpriteCalculation.DeConvertToRoot(e.Location, root_Frames_Grid_Pos),
                                                                            cur_FrameIndex);
                        int cur_ModuleIndex = -1;

                        if (cur_ModuleOfFrameIndex >= 0)
                        {
                            cur_ModuleIndex = spr.getModuleIndexFromID(spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame[cur_ModuleOfFrameIndex].ID);
                        }

                        if (cur_ModuleOfFrameIndex >= 0 && cur_ModuleIndex >= 0)
                        {
                            if (CurSel_Frame == null)
                                CurSel_Frame = new FrameSelection();
                            CurSel_Frame.CurrentFrameIndex = cur_FrameIndex;
                            CurSel_Frame.CurrentModuleOfFrameIndex = cur_ModuleOfFrameIndex;
                            CurSel_Frame.CurrentModuleIndex = cur_ModuleIndex;
                            CurSel_Frame.P1 = new Point(spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame[cur_ModuleOfFrameIndex].OX,
                                                        spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame[cur_ModuleOfFrameIndex].OY);
                            CurSel_Frame.P2 = new Point(CurSel_Frame.P1.X + spr.lst_Modules[cur_ModuleIndex].W,
                                                        CurSel_Frame.P1.Y + spr.lst_Modules[cur_ModuleIndex].H);
                        }
                        else
                        {
                            CurSel_Frame = null;
                        }
                        DrawPanelFrame();
                        updateMOFramesGridFromCurSel_Frame();
                    }
                }
            }
            FramePanelMouseDown = false;
            frames_edit_state = MODULE_RESIZE_NONE;
        }

        private void panel_Frames_MouseMove(object sender, MouseEventArgs e)
        {
            //if (spr == null || spr.spr_image == null || spr.spr_image_FileName == null)
            if (spr == null || spr.spr_image == null)
                return;

            //Modify consor
            if (frames_editor_mode == PANEL_MOVE_ROOT_MODE)
            {
                panel_Frames.Cursor = System.Windows.Forms.Cursors.Hand;
                if (FramePanelMouseDown)
                {
                    int dx = e.Location.X - FramePanelMouseDownPos.X;
                    int dy = e.Location.Y - FramePanelMouseDownPos.Y;
                    root_Frames_Grid_Pos = new Point(dx + root_Frames_Grid_Pos.X, dy + root_Frames_Grid_Pos.Y);
                    FramePanelMouseDownPos = e.Location;
                    DrawPanelFrame();
                }
            }
            else if (frames_editor_mode == PANEL_EDIT_RECT_MODE)
            {
                if (spr.lst_Frames != null && CurSel_Frame != null)
                {
                    if (frames_edit_state == FRAME_EDIT_NONE)
                    {
                        Rectangle currentRect = SpriteCalculation.ConvertToRoot(new Rectangle(CurSel_Frame.P1.X, CurSel_Frame.P1.Y,
                                                                            CurSel_Frame.P2.X - CurSel_Frame.P1.X,
                                                                            CurSel_Frame.P2.Y - CurSel_Frame.P1.Y),
                                                                            root_Frames_Grid_Pos);

                        if (SpriteCalculation.IsPointAtMiddleOfRect(e.Location, currentRect))
                        {
                            panel_Modules.Cursor = System.Windows.Forms.Cursors.SizeAll;
                        }
                        else
                        {
                            panel_Modules.Cursor = System.Windows.Forms.Cursors.Default;
                        }
                    }
                    else if (frames_edit_state == FRAME_EDIT_MOVE)
                    {
                        if (FramePanelMouseDown && FramePanelMouseDownPos != null)
                        {
                            CurSel_Frame.P1 = new Point(CurSel_Frame.P1.X + (e.Location.X - FramePanelMouseDownPos.X),
                                                    CurSel_Frame.P1.Y + (e.Location.Y - FramePanelMouseDownPos.Y));
                            CurSel_Frame.P2 = new Point(CurSel_Frame.P2.X + (e.Location.X - FramePanelMouseDownPos.X),
                                                    CurSel_Frame.P2.Y + (e.Location.Y - FramePanelMouseDownPos.Y));
                            spr.lst_Frames[CurSel_Frame.CurrentFrameIndex].lst_ModulesOfFrame[CurSel_Frame.CurrentModuleOfFrameIndex].OX = CurSel_Frame.P1.X;
                            spr.lst_Frames[CurSel_Frame.CurrentFrameIndex].lst_ModulesOfFrame[CurSel_Frame.CurrentModuleOfFrameIndex].OY = CurSel_Frame.P1.Y;
                            FramePanelMouseDownPos = e.Location;
                            DrawPanelFrame();
                        }
                    }
                }
                else
                {
                    panel_Frames.Cursor = System.Windows.Forms.Cursors.Default;
                }
            }
        }

        //========================================================================
        // Animation tab functions
        //========================================================================
        //Animaion grid
        private void button_NewAnimation_Click(object sender, EventArgs e)
        {
            newAnimation();
        }

        private void button_DeleteAnimation_Click(object sender, EventArgs e)
        {
            deleteAnimation();
        }

        private void button_CloneAnimation_Click(object sender, EventArgs e)
        {
            cloneAnimation();
        }

        private void button_UpAnimation_Click(object sender, EventArgs e)
        {
            upAnimation();
        }

        private void button_DownAnimation_Click(object sender, EventArgs e)
        {
            downAnimation();
        }

        private void dataGridView_Animations_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            DrawPanelAnimation();
        }

        private void dataGridView_Animations_SelectionChanged(object sender, EventArgs e)
        {
            updateCurAnimSelection();
            DrawPanelAnimation();
            StopAnim();
        }

        //Frames Of Animaion grid
        private void button_NewFrameOfAnimation_Click(object sender, EventArgs e)
        {
            newFrameOfAnim();
        }

        private void button_DeleteFrameOfAnimation_Click(object sender, EventArgs e)
        {
            deleteFrameOfAnim();
        }

        private void button_CloneFrameOfAnimation_Click(object sender, EventArgs e)
        {
            cloneFrameOfAnim();
        }

        private void button_UpFrameOfAnimation_Click(object sender, EventArgs e)
        {
            upFrameOfAnim();
        }

        private void button_DownFrameOfAnimation_Click(object sender, EventArgs e)
        {
            downFrameOfAnim();
        }

        private void dataGridView_FramesOfAnimation_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            DrawPanelAnimation();
        }

        bool bAnimationUpdateSelection = true;
        private void dataGridView_FramesOfAnimation_SelectionChanged(object sender, EventArgs e)
        {
            if (bAnimationUpdateSelection == true)
            {
                updateCurFOAnimsSelection();
            }
            bAnimationUpdateSelection = true;
        }

        private void playAnimationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //countdown = 100;
            //Anim_timer.Start();
        }

        //Panel Animation

        private static int anim_idx = 0;
        private static List<int> anim_queue;

        private void Anim_timer_Tick(object sender, EventArgs e)
        {
            setCurrentFOAnimsOnGrid(anim_queue[anim_idx]);
            anim_idx++;

            if (anim_idx >= anim_queue.Count)
            {
                anim_idx = 0;
            }

            //int cur_IndexAnim = dataGridView_Animations.CurrentRow.Index;
            //int cur_IndexFOA = dataGridView_FramesOfAnimation.CurrentRow.Index;
            //int total_FsOA = dataGridView_FramesOfAnimation.Rows.Count;

            //if (total_FsOA > 0)
            //{
            //    int next_IndexFOA = (cur_IndexFOA + 1) % total_FsOA;

            //    dataGridView_FramesOfAnimation.CurrentCell = dataGridView_FramesOfAnimation.Rows[next_IndexFOA].Cells[0];
            //    dataGridView_FramesOfAnimation.Rows[next_IndexFOA].Selected = true;

            //    dataGridView_FramesOfAnimation.Refresh();

            //    anim_idx++;
            //}
        }

        private void button_PlayAnim_Click(object sender, EventArgs e)
        {
            if (is_PlayingAnim)
            {
                StopAnim();
            }
            else
            {
                PlayAnim();
            }
        }

        private void numericUpDown_FPS_ValueChanged(object sender, EventArgs e)
        {
            if (is_PlayingAnim)
            {
                PlayAnim();
            }
        }

        private void dataGridView_FramesOfAnimation_MouseClick(object sender, MouseEventArgs e)
        {
            StopAnim();
        }

        private void panel_Animations_Paint(object sender, PaintEventArgs e)
        {
            DrawPanelAnimation();
        }

        private void panel_Animations_MouseDown(object sender, MouseEventArgs e)
        {
            panelAnimationsMouseDrag = true;
            if (spr == null || spr.spr_image == null)// || spr.sprite_FileName == null)
                return;

            if (e.Button == MouseButtons.Right)
            {

            }
            else if (e.Button == MouseButtons.Left)
            {
                if (animations_editor_mode == PANEL_MOVE_ROOT_MODE)
                {

                }
                else if (animations_editor_mode == PANEL_EDIT_RECT_MODE)
                {
                    if (spr.lst_Animations != null
                        && spr.lst_Animations[dataGridView_Animations.CurrentRow.Index].lst_FramesOfAnimation!= null
                        && CurSel_Animation != null)
                    {
                        Rectangle currentRect = SpriteCalculation.ConvertToRoot(new Rectangle(CurSel_Animation.P1.X, CurSel_Animation.P1.Y,
                                                                            CurSel_Animation.P2.X - CurSel_Animation.P1.X,
                                                                            CurSel_Animation.P2.Y - CurSel_Animation.P1.Y),
                                                                            root_Animations_Grid_Pos);

                        if (SpriteCalculation.IsPointInRect(e.Location, currentRect))
                        {
                            animations_edit_state = ANIMATION_EDIT_MOVE;
                        }
                        else
                        {
                            animations_edit_state = ANIMATION_EDIT_NONE;
                        }
                    }
                }
            }
            AnimationPanelMouseDown = true;
            AnimationPanelMouseDownPos = e.Location;
        }

        private void panel_Animations_MouseUp(object sender, MouseEventArgs e)
        {
            panelAnimationsMouseDrag = false;
            //if (spr == null || spr.spr_image == null || spr.spr_image_FileName == null)
            if (spr == null || spr.spr_image == null)
                return;

            if (e.Button == MouseButtons.Right)
            {
                animations_editor_mode++;
                animations_editor_mode = animations_editor_mode % 2;
                DrawPanelAnimation();
            }
            else if (e.Button == MouseButtons.Left)
            {
                if (animations_editor_mode == PANEL_MOVE_ROOT_MODE)
                {

                }
                else if (animations_editor_mode == PANEL_EDIT_RECT_MODE)
                {
                    if (spr.lst_Animations != null && dataGridView_Animations.CurrentRow != null
                        && spr.lst_Animations[dataGridView_Animations.CurrentRow.Index].lst_FramesOfAnimation != null)
                    {
                        int cur_AnimationIndex = dataGridView_Animations.CurrentRow.Index;

                        int cur_FrameOfAnimationIndex = dataGridView_FramesOfAnimation.CurrentRow.Index;

                        int cur_FrameIndex = -1;

                        if (cur_FrameOfAnimationIndex >= 0)
                        {
                            cur_FrameIndex = spr.getFrameIndexFromID(spr.lst_Animations[cur_AnimationIndex].lst_FramesOfAnimation[cur_FrameOfAnimationIndex].ID);
                        }

                        if (cur_FrameOfAnimationIndex >= 0 && cur_FrameIndex >= 0)
                        {
                            if (CurSel_Animation == null)
                                CurSel_Animation = new AnimationSelection();
                            CurSel_Animation.CurrentAnimationIndex = cur_AnimationIndex;
                            CurSel_Animation.CurrentFrameOfAnimationIndex = cur_FrameOfAnimationIndex;
                            CurSel_Animation.CurrentFrameIndex = cur_FrameIndex;
                            CurSel_Animation.P1 = new Point(spr.lst_Animations[cur_AnimationIndex].lst_FramesOfAnimation[cur_FrameOfAnimationIndex].OX + spr.lst_Animations[cur_AnimationIndex].lst_FramesOfAnimation[cur_FrameOfAnimationIndex].getFramFromId().X,
                                                spr.lst_Animations[cur_AnimationIndex].lst_FramesOfAnimation[cur_FrameOfAnimationIndex].OY + spr.lst_Animations[cur_AnimationIndex].lst_FramesOfAnimation[cur_FrameOfAnimationIndex].getFramFromId().Y);
                            CurSel_Animation.P2 = new Point(CurSel_Animation.P1.X + spr.lst_Frames[cur_FrameIndex].W,
                                                        CurSel_Animation.P1.Y + spr.lst_Frames[cur_FrameIndex].H);
                        }
                        else
                        {
                            CurSel_Animation = null;
                        }
                        DrawPanelAnimation();
                        updateFOAminssGridFromCurSel_Anim();
                    }
                }
            }
            AnimationPanelMouseDown = false;
            animations_edit_state = MODULE_RESIZE_NONE;
        }

        private void panel_Animations_MouseMove(object sender, MouseEventArgs e)
        {
        	
            //if (spr == null || spr.spr_image == null || spr.spr_image_FileName == null)
            if (spr == null || spr.spr_image == null)
                return;
            
            //Modify consor
            if (animations_editor_mode == PANEL_MOVE_ROOT_MODE)
            {
                panel_Animations.Cursor = System.Windows.Forms.Cursors.Hand;
                if (AnimationPanelMouseDown)
                {
                    int dx = e.Location.X - AnimationPanelMouseDownPos.X;
                    int dy = e.Location.Y - AnimationPanelMouseDownPos.Y;
                    root_Animations_Grid_Pos = new Point(dx + root_Animations_Grid_Pos.X, dy + root_Animations_Grid_Pos.Y);
                    AnimationPanelMouseDownPos = e.Location;
                    DrawPanelAnimation();
                }
            }
            else if (animations_editor_mode == PANEL_EDIT_RECT_MODE)
            {
                if (spr.lst_Animations != null && CurSel_Animation != null)
                {
                    if (animations_edit_state == ANIMATION_EDIT_NONE)
                    {
                        Rectangle currentRect = SpriteCalculation.ConvertToRoot(new Rectangle(CurSel_Animation.P1.X, CurSel_Animation.P1.Y,
                                                                            CurSel_Animation.P2.X - CurSel_Animation.P1.X,
                                                                            CurSel_Animation.P2.Y - CurSel_Animation.P1.Y),
                                                                            root_Animations_Grid_Pos);

                        if (SpriteCalculation.IsPointAtMiddleOfRect(e.Location, currentRect))
                        {
                            panel_Animations.Cursor = System.Windows.Forms.Cursors.SizeAll;
                        }
                        else
                        {
                            panel_Animations.Cursor = System.Windows.Forms.Cursors.Default;
                        }
                    }
                    else if (animations_edit_state == ANIMATION_EDIT_MOVE)
                    {
                        if (AnimationPanelMouseDown && AnimationPanelMouseDownPos != null)
                        {
                           
                            CurSel_Animation.P1 = new Point(CurSel_Animation.P1.X + (e.Location.X - AnimationPanelMouseDownPos.X),
                                                    CurSel_Animation.P1.Y + (e.Location.Y - AnimationPanelMouseDownPos.Y));
                            CurSel_Animation.P2 = new Point(CurSel_Animation.P2.X + (e.Location.X - AnimationPanelMouseDownPos.X),
                                                    CurSel_Animation.P2.Y + (e.Location.Y - AnimationPanelMouseDownPos.Y));
                            spr.lst_Animations[CurSel_Animation.CurrentAnimationIndex].lst_FramesOfAnimation[CurSel_Animation.CurrentFrameOfAnimationIndex].OX = CurSel_Animation.P1.X - spr.lst_Animations[CurSel_Animation.CurrentAnimationIndex].lst_FramesOfAnimation[CurSel_Animation.CurrentFrameOfAnimationIndex].getFramFromId().X;
                            spr.lst_Animations[CurSel_Animation.CurrentAnimationIndex].lst_FramesOfAnimation[CurSel_Animation.CurrentFrameOfAnimationIndex].OY = CurSel_Animation.P1.Y -  spr.lst_Animations[CurSel_Animation.CurrentAnimationIndex].lst_FramesOfAnimation[CurSel_Animation.CurrentFrameOfAnimationIndex].getFramFromId().Y;
                            AnimationPanelMouseDownPos = e.Location;
                            DrawPanelAnimation();
                        }
                    }
                }
                else
                {
                    panel_Animations.Cursor = System.Windows.Forms.Cursors.Default;
                }
            }
        }

        //Panel Animation
        private void flowLayoutPanel_Animation_Paint(object sender, PaintEventArgs e)
        {
            //DrawFlowPanelAnimation();
        }

        private void frames_flow_panel_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            OwnPanel frames_flow_panel = (OwnPanel)sender;

            //MessageBox.Show("Current frame index : " + frames_flow_panel.CurrentIndex.ToString());
            updateFlowPanelAnimationSelection(frames_flow_panel.CurrentIndex);
            newFrameOfAnim();
        }

        private void frames_flow_panel_MouseClick(object sender, MouseEventArgs e)
        {
            OwnPanel frames_flow_panel = (OwnPanel)sender;

            //MessageBox.Show("Current frame index : " + frames_flow_panel.CurrentIndex.ToString());
            updateFlowPanelAnimationSelection(frames_flow_panel.CurrentIndex);
        }

        private void panel_Modules_MouseEnter(object sender, EventArgs e)
        {
            panel_Modules.Focus();
        }
        public  void drawStatusBar(){
        	 //test
        	 BarColor.Text = " x:  " + root_Modules_Grid_Pos_Scale.X +" , y :  " +root_Modules_Grid_Pos_Scale.Y;
        	
        	 //end text
        	Point cursorLocation = SpriteCalculation.DeConvertToRoot(mouseCurrentPos, root_Modules_Grid_Pos_Scale);
        	int dx = (int)(cursorLocation.X/m_ZoomInModule );
        	int dy = (int)(cursorLocation.Y/m_ZoomInModule);       	 
        	 BarCursor.Text = "Zoom :" +Math.Round(m_ZoomInModule*100) +"%    |      "+dx.ToString() + " : " + dy.ToString();
        }

        private void panel_Modules_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
           

            isArrowKeyPressed = e.KeyCode == Keys.Up || e.KeyCode == Keys.Down ||
                     e.KeyCode == Keys.Left || e.KeyCode == Keys.Right;

            

            if (isArrowKeyPressed)
                e.IsInputKey = true;
        
        }

        } 
     
}
